home *** CD-ROM | disk | FTP | other *** search
- *
- * 6526.asm - CIA-Emulation
- *
- * Copyright (C) 1994-1995 by Christian Bauer
- *
-
- *
- * Anmerkungen:
- * ------------
- *
- * Funktionsweise/Periodic:
- * - Für jede (simulierte) C64-Rasterzeile wird vom 6510-Task die Routine
- * Periodic6526 aufgerufen, die die Timer herunterzählt, ggf. Interrupts
- * auslöst und die Joysticks abfragt
- *
- * Timer/Latches:
- * - Die Bytefolge im Register-File ist gegenüber dem echten 6526 umgekehrt,
- * das wird aber bei den WriteTo6526- und ReadFrom6526-Routinen wieder
- * ausgeglichen
- *
- * TOD-Clocks:
- * - Die TODs werden synchron mit dem VBlank gezählt. Es wird also ein
- * 50Hz-Eingangssignal simuliert.
- *
- * Tastaturabfrage:
- * - Das Feld KeyMatrix enthält für jede Taste entsprechend der C64-
- * Tastaturmatrix ein Bit (0: Taste gedrückt, 1: Taste nicht gedrückt)
- * - Bei Lesezugriffen aus CIA-A, Port B werden entsprechend der aktiven
- * (ausgewählten) Zeilen der Tastatur die entsprechenden Bits aus der
- * Tastaturmatrix zusammengestellt
- * - Die Help-Taste löst einen NMI aus (Restore), F10 einen RESET
- *
- * Inkompatibilitäten:
- * - Die TOD-Clock sollte bei einem Lesezugriff nicht angehalten,
- * sondern gelatcht werden
- * - Kein Lightpen-Interrupt (CIA-A, PB4)
- *
-
- MACHINE 68020
-
- XREF ShowPrefs ;Main.asm
- XREF ResetC64
-
- XREF _ciaaprb
- XREF _ciaaddrb
-
- XREF IntIsNMI ;6510.asm
- XREF IntIsCIAIRQ
- XREF NMIState
- XREF Peri6526Cont
-
- XREF ChangedVA ;6569.asm
-
- XREF IECIsOpen ;IEC.asm
-
- XDEF Reset6526
- XDEF _GetCIA1Dump
- XDEF _GetCIA2Dump
- XDEF ReadFrom6526A
- XDEF ReadFrom6526B
- XDEF WriteTo6526A
- XDEF WriteTo6526B
- XDEF Periodic6526
- XDEF ChangedKeys
- XDEF CountTODs
- XDEF _KeyPressed
-
- XDEF CIACycles ;Prefs
- XDEF Joystick1On
- XDEF Joystick2On
- XDEF JoystickSwap
- XDEF KeyboardYZ
-
- SECTION "text",CODE
-
- **
- ** Definitionen
- **
-
- ; CIA-Register
- PRA = 0
- PRB = 1
- DDRA = 2
- DDRB = 3
- TAHI = 4 ;Timer-Wert A
- TALO = 5 ;Achtung: Umgekehrte Bytefolge!
- TBHI = 6 ;Timer-Wert B
- TBLO = 7
- TOD10THS = 8
- TODSEC = 9
- TODMIN = 10
- TODHR = 11
- SDR = 12
- ICR = 13 ;Interrupt-Data
- CRA = 14
- CRB = 15
-
- ; Zusätzliche Register
- LTCHA = 16 ;Timer-Latch A
- LTCHB = 18 ;Timer-Latch B
- INTMASK = 20 ;Interrupt-Enable
- TODHALT = 21 ;TOD zwecks Beschreiben/Auslesen gestoppt
- ALM10THS = 22 ;Alarmzeit
- ALMSEC = 23
- ALMMIN = 24
- ALMHR = 25
- TODDIV = 26 ;TOD-Frequenzteiler
- TACNTPHI2 = 27 ;Timer A läuft und zählt Phi2
- TBCNTPHI2 = 28 ;Timer B läuft und zählt Phi2
- TBCNTTA = 29 ;Timer B läuft und zählt Unterläufe von Timer A
-
-
- **
- ** CIAs zurücksetzen
- **
-
- ; CIA-A
- Reset6526 lea Registers1,a0
- clr.l (a0)
- clr.l 4(a0)
- clr.l 8(a0)
- clr.l 12(a0)
- move.w #-1,TAHI(a0) ;Timer auf -1
- move.w #-1,TBHI(a0)
-
- move.w #$0001,LTCHA(a0) ;Latches auf 1
- move.w #$0001,LTCHB(a0)
- clr.b INTMASK(a0) ;Interrupts abschalten
- clr.b TODHALT(a0) ;TOD läuft
- clr.l ALM10THS(a0) ;Alarmzeit auf 00:00:00.0
- clr.w TACNTPHI2(a0) ;Beide Timer anhalten
-
- move.b #$ff,Joystick1 ;Joystick inaktiv
- move.b #$ff,Joystick2
- move.b #$ff,Joystick2Key
-
- ; CIA-B
- lea Registers2,a0
- clr.l (a0)
- clr.l 4(a0)
- clr.l 8(a0)
- clr.l 12(a0)
- move.w #-1,TAHI(a0) ;Timer auf -1
- move.w #-1,TBHI(a0)
-
- move.w #$0001,LTCHA(a0) ;Latches auf 1
- move.w #$0001,LTCHB(a0)
- clr.b INTMASK(a0) ;Interrupts abschalten
- clr.b TODHALT(a0) ;TOD läuft
- clr.l ALM10THS(a0) ;Alarmzeit auf 00:00:00.0
- clr.w TACNTPHI2(a0) ;Beide Timer anhalten
-
- ; Tastaturmatrix löschen
- moveq #-1,d0
- move.l d0,KeyMatrix
- move.l d0,KeyMatrix+4
-
- ; VIC-Bank 0 einstellen
- moveq #0,d0
- bra ChangedVA
-
-
- **
- ** CIA-Status in Datenstruktur schreiben
- **
-
- _GetCIA1Dump lea Registers1,a0
- bra GetCIADump
-
- _GetCIA2Dump lea Registers2,a0
-
- GetCIADump move.l 4(sp),a1
- move.l (a0),(a1)+
- move.b TALO(a0),(a1)+ ;Wegen umgekehrter Bytefolge
- move.b TAHI(a0),(a1)+
- move.b TBLO(a0),(a1)+
- move.b TBHI(a0),(a1)+
- move.l TOD10THS(a0),(a1)+
- move.l SDR(a0),(a1)+
-
- move.b LTCHA+1(a0),(a1)+
- move.b LTCHA(a0),(a1)+
- move.b LTCHB+1(a0),(a1)+
- move.b LTCHB(a0),(a1)+
- move.l ALM10THS(a0),(a1)+
- move.b INTMASK(a0),(a1)
- rts
-
-
- **
- ** Tastaturbelegung geändert, Y und Z sortieren
- **
-
- ChangedKeys tst.w KeyboardYZ
- bne 1$
- move.l #$00010004,KeyPatch1
- move.l #$00030001,KeyPatch2
- rts
- 1$ move.l #$00030001,KeyPatch1
- move.l #$00010004,KeyPatch2
- rts
-
-
- **
- ** In ein CIA-A-Register schreiben
- ** d0.w: Registernummer ($00-$0f)
- ** d1.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- WriteTo6526A lea Registers1,a0
- move.l WriteTabA(pc,d0.w*4),a1
- jmp (a1)
-
- CNOP 0,4
- WriteTabA dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrNormal
- dc.l WrTALO
- dc.l WrTAHI
- dc.l WrTBLO
- dc.l WrTBHI
- dc.l WrTOD10THS
- dc.l WrTODSEC
- dc.l WrTODMIN
- dc.l WrTODHR
- dc.l WrNormal
- dc.l WrAICR
- dc.l WrCRA
- dc.l WrCRB
-
- WrNormal move.b d1,(a0,d0.w)
- rts
-
- WrTALO move.b d1,LTCHA+1(a0)
- rts
-
- WrTAHI move.b d1,LTCHA(a0)
- btst #0,CRA(a0) ;Timer A gestoppt?
- bne 1$
- move.w LTCHA(a0),TAHI(a0) ;Ja, Timer laden
- 1$ rts
-
- WrTBLO move.b d1,LTCHB+1(a0)
- rts
-
- WrTBHI move.b d1,LTCHB(a0)
- btst #0,CRB(a0) ;Timer B gestoppt?
- bne 1$
- move.w LTCHB(a0),TBHI(a0) ;Ja, Timer laden
- 1$ rts
-
- WrTOD10THS and.b #$0f,d1
- clr.b TODHALT(a0) ;TOD weiterlaufen lassen
- btst #7,CRB(a0) ;Alarm-Zeit schreiben?
- bne 1$
- move.b d1,TOD10THS(a0)
- rts
- 1$ move.b d1,ALM10THS(a0)
- rts
-
- WrTODSEC and.b #$7f,d1
- btst #7,CRB(a0) ;Alarm-Zeit schreiben?
- bne 1$
- move.b d1,TODSEC(a0)
- rts
- 1$ move.b d1,ALMSEC(a0)
- rts
-
- WrTODMIN and.b #$7f,d1
- btst #7,CRB(a0) ;Alarm-Zeit schreiben?
- bne 1$
- move.b d1,TODMIN(a0)
- rts
- 1$ move.b d1,ALMMIN(a0)
- rts
-
- WrTODHR and.b #$9f,d1
- st.b TODHALT(a0) ;TOD anhalten
- btst #7,CRB(a0) ;Alarm-Zeit schreiben?
- bne 1$
- move.b d1,TODHR(a0)
- rts
- 1$ move.b d1,ALMHR(a0)
- rts
-
- WrAICR bclr #7,d1 ;S/C-Bit löschen
- bne 1$ ;War es gesetzt?
- not.b d1 ;Nein, Bits zum Löschen negieren
- and.b d1,INTMASK(a0) ;Und Bits löschen
- bra 2$
- 1$ or.b d1,INTMASK(a0) ;Bits setzen
- 2$
- move.b ICR(a0),d0 ;Anstehende Interrupts erlaubt?
- and.b INTMASK(a0),d0
- and.b #$1f,d0
- beq 3$
- or.b #$80,ICR(a0) ;Ja, IRQ auslösen
- st.b IntIsCIAIRQ
- rts
- 3$ and.b #$7f,ICR(a0) ;Nein, IRQ zurücknehmen
- clr.b IntIsCIAIRQ
- rts
-
- WrCRA bclr #4,d1 ;Force load?
- beq 1$
- move.w LTCHA(a0),TAHI(a0) ;Ja, Timer laden
- 1$ move.b d1,CRA(a0)
-
- and.b #$21,d1 ;Läuft der Timer und zählt er Phi2?
- cmp.b #$01,d1
- seq.b TACNTPHI2(a0) ;Ja, Flag setzen
- rts
-
- WrCRB bclr #4,d1 ;Force load?
- beq 1$
- move.w LTCHB(a0),TBHI(a0) ;Ja, Timer laden
- 1$ move.b d1,CRB(a0)
-
- and.b #$61,d1 ;Läuft der Timer und zählt er Phi2?
- cmp.b #$01,d1
- seq.b TBCNTPHI2(a0) ;Ja, Flag setzen
- cmp.b #$41,d1 ;Läuft er und zählt Unterläuft von Timer A?
- seq.b TBCNTTA(a0) ;Ja, Flag setzen
- rts
-
-
- **
- ** In ein CIA-B-Register schreiben
- ** d0.w: Registernummer ($00-$0f)
- ** d1.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- WriteTo6526B lea Registers2,a0
- move.l WriteTabB(pc,d0.w*4),a1
- jmp (a1)
-
- CNOP 0,4
- WriteTabB dc.l WrBPRA
- dc.l WrNormal
- dc.l WrBDDRA
- dc.l WrNormal
- dc.l WrTALO
- dc.l WrTAHI
- dc.l WrTBLO
- dc.l WrTBHI
- dc.l WrTOD10THS
- dc.l WrTODSEC
- dc.l WrTODMIN
- dc.l WrTODHR
- dc.l WrNormal
- dc.l WrBICR
- dc.l WrCRA
- dc.l WrCRB
-
- WrBPRA move.b d1,PRA(a0) ;Floppy/VA
- tst.b IECIsOpen ;Wenn IEC aktiv ist, Port setzen
- beq WrBNewVA
- move.b d1,_ciaaprb
- bra WrBNewVA
-
- WrBDDRA move.b d1,DDRA(a0) ;Floppy/VA
- tst.b IECIsOpen ;Wenn IEC aktiv ist, DDR setzen
- beq WrBNewVA
- move.b d1,_ciaaddrb
- WrBNewVA move.b DDRA(a0),d0 ;VA extrahieren
- not.b d0
- or.b PRA(a0),d0
- not.b d0
- and.b #$03,d0
- bra ChangedVA ;Und dem VIC mitteilen
-
- WrBICR bclr #7,d1 ;S/C-Bit löschen
- bne 1$ ;War es gesetzt?
- not.b d1 ;Nein, Bits zum Löschen negieren
- and.b d1,INTMASK(a0) ;Und Bits löschen
- bra 2$
- 1$ or.b d1,INTMASK(a0) ;Bits setzen
- 2$
- move.b ICR(a0),d0 ;Anstehende Interrupts erlaubt?
- and.b INTMASK(a0),d0
- and.b #$1f,d0
- beq 3$
- or.b #$80,ICR(a0) ;Ja, NMI auslösen
- tst.b NMIState
- bne 4$
- st.b NMIState
- st.b IntIsNMI
- 4$ rts
- 3$ and.b #$7f,ICR(a0) ;Nein, NMI zurücknehmen
- clr.b NMIState
- rts
-
-
- **
- ** Aus einem CIA-A-Register lesen
- ** d0.w: Registernummer ($00-$0f)
- ** Rückgabe: d0.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- ReadFrom6526A lea Registers1,a0
- move.l ReadTabA(pc,d0.w*4),a1
- jmp (a1)
-
- CNOP 0,4
- ReadTabA dc.l RdAPRA
- dc.l RdAPRB
- dc.l RdANormal
- dc.l RdANormal
- dc.l RdATALO
- dc.l RdATAHI
- dc.l RdATBLO
- dc.l RdATBHI
- dc.l RdATOD10THS
- dc.l RdANormal
- dc.l RdANormal
- dc.l RdATODHR
- dc.l RdANormal
- dc.l RdAICR
- dc.l RdANormal
- dc.l RdANormal
-
- RdANormal move.b (a0,d0.w),d0
- rts
-
- RdAPRA move.b DDRA(a0),d0
- not.b d0
- or.b PRA(a0),d0
- and.b Joystick2,d0
- rts
-
- RdAPRB lea KeyMatrix,a1
- move.b PRA(a0),d1 ;Tastaturabfrage
- move.b #$ff,d0 ;Alle aktiven Reihen dazuANDen
- lsr.b #1,d1
- bcs 1$
- and.b (a1),d0
- 1$ lsr.b #1,d1
- bcs 2$
- and.b 1(a1),d0
- 2$ lsr.b #1,d1
- bcs 3$
- and.b 2(a1),d0
- 3$ lsr.b #1,d1
- bcs 4$
- and.b 3(a1),d0
- 4$ lsr.b #1,d1
- bcs 5$
- and.b 4(a1),d0
- 5$ lsr.b #1,d1
- bcs 6$
- and.b 5(a1),d0
- 6$ lsr.b #1,d1
- bcs 7$
- and.b 6(a1),d0
- 7$ lsr.b #1,d1
- bcs 8$
- and.b 7(a1),d0
-
- 8$ and.b Joystick1,d0
- move.b DDRB(a0),d1
- not.b d1
- or.b PRB(a0),d1
- and.b d1,d0
- rts
-
- RdATALO move.b TALO(a0),d0 ;Weil die Timer im Registerfile
- rts ;als big-endian gespeichert sind
-
- RdATAHI move.b TAHI(a0),d0
- rts
-
- RdATBLO move.b TBLO(a0),d0
- rts
-
- RdATBHI move.b TBHI(a0),d0
- rts
-
- RdATOD10THS move.b TOD10THS(a0),d0
- clr.b TODHALT(a0) ;TOD weiterlaufen lassen
- rts
-
- RdATODHR st.b TODHALT(a0) ;TOD anhalten
- move.b TODHR(a0),d0
- rts
-
- RdAICR move.b ICR(a0),d0 ;ICR beim Lesen löschen
- clr.b ICR(a0)
- clr.b IntIsCIAIRQ ;IRQ zurücknehmen
- rts
-
-
- **
- ** Aus einem CIA-B-Register lesen
- ** d0.w: Registernummer ($00-$0f)
- ** Rückgabe: d0.b: Byte
- **
- ** Darf das obere Wort von d0 und d1 nicht verändern!
- **
-
- ReadFrom6526B lea Registers2,a0
- move.l ReadTabB(pc,d0.w*4),a1
- jmp (a1)
-
- CNOP 0,4
- ReadTabB dc.l RdBPRA
- dc.l RdBPRB
- dc.l RdBNormal
- dc.l RdBNormal
- dc.l RdBTALO
- dc.l RdBTAHI
- dc.l RdBTBLO
- dc.l RdBTBHI
- dc.l RdBTOD10THS
- dc.l RdBNormal
- dc.l RdBNormal
- dc.l RdBTODHR
- dc.l RdBNormal
- dc.l RdBICR
- dc.l RdBNormal
- dc.l RdBNormal
-
- RdBNormal move.b (a0,d0.w),d0
- rts
-
- RdBPRA move.b DDRA(a0),d0 ;Floppy/VA
- not.b d0
- or.b PRA(a0),d0
-
- tst.b IECIsOpen ;Wenn IEC aktiv ist, davon lesen
- beq 1$
- and.b #$03,d0
- move.b _ciaaprb,d1
- and.b #$fc,d1
- or.b d1,d0
- 1$ rts
-
- RdBPRB move.b DDRB(a0),d0 ;Userport
- not.b d0 ;Eingabebits immer 1
- or.b PRB(a0),d0
- rts
-
- RdBTALO move.b TALO(a0),d0 ;Weil die Timer im Registerfile
- rts ;als big-endian gespeichert sind
-
- RdBTAHI move.b TAHI(a0),d0
- rts
-
- RdBTBLO move.b TBLO(a0),d0
- rts
-
- RdBTBHI move.b TBHI(a0),d0
- rts
-
- RdBTOD10THS move.b TOD10THS(a0),d0
- clr.b TODHALT(a0) ;TOD weiterlaufen lassen
- rts
-
- RdBTODHR st.b TODHALT(a0) ;TOD anhalten
- move.b TODHR(a0),d0
- rts
-
- RdBICR move.b ICR(a0),d0 ;ICR beim Lesen löschen
- clr.b ICR(a0)
- clr.b NMIState ;NMI zurücknehmen
- rts
-
-
- **
- ** Wird jede Rasterzeile einmal aufgerufen
- **
-
- *
- * CIA-A
- * d1: ICR
- * d2: INTMASK
- * d3: CIACycles
- *
-
- Periodic6526 lea Registers1,a0
- move.b ICR(a0),d1
- move.b INTMASK(a0),d2
- move.w CIACycles,d3
-
- *
- * Timer A
- *
-
- tst.b TACNTPHI2(a0) ;Wird Phi2 gezählt?
- beq CiaATADone
-
- sub.w d3,TAHI(a0) ;Ja, herabzählen
- bcc CiaATADone ;Unterlauf?
-
- or.b #$01,d1 ;Ja, IRQ-Bit setzen
- btst #0,d2 ;IRQ freigegeben?
- beq CiaATANoIRQ
- or.b #$80,d1 ;Ja, IR-Bit setzen
- st.b IntIsCIAIRQ ;und IRQ auslösen
-
- CiaATANoIRQ move.w LTCHA(a0),TAHI(a0) ;Zähler neu laden
- btst #3,CRA(a0) ;One-Shot?
- beq 1$
- and.b #$fe,CRA(a0) ;Ja, Zähler stoppen
- clr.b TACNTPHI2(a0)
-
- 1$ tst.b TBCNTTA(a0) ;Läuft Timer B und zählt er
- beq CiaATADone ; Unterläufe von Timer A?
-
- subq.w #1,TBHI(a0) ;Ja, Timer B runterzählen
- bcs CiaATBUnderflow ;Untergelaufen?
- CiaATADone
-
- *
- * Timer B
- *
-
- tst.b TBCNTPHI2(a0) ;Wird Phi2 gezählt?
- beq CiaATBDone
-
- sub.w d3,TBHI(a0) ;Ja, herabzählen
- bcc CiaATBDone ;Unterlauf?
-
- CiaATBUnderflow or.b #$02,d1 ;Ja, IRQ-Bit setzen
- btst #1,d2 ;IRQ freigegeben?
- beq CiaATBNoIRQ
- or.b #$80,d1 ;Ja, IR-Bit setzen
- st.b IntIsCIAIRQ ;und IRQ auslösen
-
- CiaATBNoIRQ move.w LTCHB(a0),TBHI(a0) ;Zähler neu laden
- btst #3,CRB(a0) ;One-Shot?
- beq CiaATBDone
- and.b #$fe,CRB(a0) ;Ja, Zähler stoppen
- clr.b TBCNTPHI2(a0)
- clr.b TBCNTTA(a0)
- CiaATBDone
-
- *
- * ICR zurückschreiben
- *
-
- move.b d1,ICR(a0)
-
- *
- * CIA-B
- * d1: ICR
- * d2: INTMASK
- * d3: CIACycles
- *
-
- lea Registers2,a0
- move.b ICR(a0),d1
- move.b INTMASK(a0),d2
-
- *
- * Timer A
- *
-
- tst.b TACNTPHI2(a0) ;Wird Phi2 gezählt?
- beq CiaBTADone
-
- sub.w d3,TAHI(a0) ;Ja, herabzählen
- bcc CiaBTADone ;Unterlauf?
-
- or.b #$01,d1 ;Ja, IRQ-Bit setzen
- btst #0,d2 ;IRQ freigegeben?
- beq CiaBTANoIRQ
- or.b #$80,d1 ;Ja, IR-Bit setzen
- tst.b NMIState ;NMI schon ausgelöst?
- bne 1$
- st.b NMIState ;Nein, NMI auslösen
- st.b IntIsNMI
- 1$
-
- CiaBTANoIRQ move.w LTCHA(a0),TAHI(a0) ;Zähler neu laden
- btst #3,CRA(a0) ;One-Shot?
- beq 1$
- and.b #$fe,CRA(a0) ;Ja, Zähler stoppen
- clr.b TACNTPHI2(a0)
-
- 1$ tst.b TBCNTTA(a0) ;Läuft Timer B und zählt er
- beq CiaBTADone ; Unterläufe von Timer A?
-
- subq.w #1,TBHI(a0) ;Ja, Timer B runterzählen
- bcs CiaBTBUnderflow ;Untergelaufen?
- CiaBTADone
-
- *
- * Timer B
- *
-
- tst.b TBCNTPHI2(a0) ;Wird Phi2 gezählt?
- beq CiaBTBDone
-
- sub.w d3,TBHI(a0) ;Ja, herabzählen
- bcc CiaBTBDone ;Unterlauf?
-
- CiaBTBUnderflow or.b #$02,d1 ;Ja, IRQ-Bit setzen
- btst #1,d2 ;IRQ freigegeben?
- beq CiaBTBNoIRQ
- or.b #$80,d1 ;Ja, IR-Bit setzen
- tst.b NMIState ;NMI schon ausgelöst?
- bne 1$
- st.b NMIState ;Nein, NMI auslösen
- st.b IntIsNMI
- 1$
-
- CiaBTBNoIRQ move.w LTCHB(a0),TBHI(a0) ;Zähler neu laden
- btst #3,CRB(a0) ;One-Shot?
- beq CiaBTBDone
- and.b #$fe,CRB(a0) ;Ja, Zähler stoppen
- clr.b TBCNTPHI2(a0)
- clr.b TBCNTTA(a0)
- CiaBTBDone
-
- *
- * ICR zurückschreiben
- *
-
- move.b d1,ICR(a0)
-
- ; In 6510-Task zurückspringen
- bra Peri6526Cont
-
-
- **
- ** TODs zählen
- **
-
- *
- * CIA-A
- *
-
- CountTODs lea Registers1,a0
- subq.b #1,TODDIV(a0) ;Frequenzteiler herabzählen
- bpl CiaATODNop
-
- btst #7,CRA(a0) ;Untergelaufen,
- beq CiaATOD60Hz ; je nach 50/60Hz-Flag neu laden
- move.b #4,TODDIV(a0)
- bra CiaATODLoaded
- CiaATOD60Hz move.b #5,TODDIV(a0)
-
- CiaATODLoaded move #0,ccr ;X löschen
- move.b #1,d0 ;1/10 Sekunden erhöhen
- move.b TOD10THS(a0),d1
- abcd d0,d1
- move.b d1,TOD10THS(a0)
- cmp.b #$10,d1 ;Über 10?
- blo CiaATODDone
-
- clr.b TOD10THS(a0) ;Ja, 1/10 Sekunden auf Null setzen
- move #0,ccr ;und Sekunden erhöhen
- move.b #1,d0
- move.b TODSEC(a0),d1
- abcd d0,d1
- move.b d1,TODSEC(a0)
- cmp.b #$60,d1 ;Über 60?
- blo CiaATODDone
-
- clr.b TODSEC(a0) ;Ja, Sekunden auf Null setzen
- move #0,ccr ;und Minuten erhöhen
- move.b #1,d0
- move.b TODMIN(a0),d1
- abcd d0,d1
- move.b d1,TODMIN(a0)
- cmp.b #$60,d1 ;Über 60?
- blo CiaATODDone
-
- clr.b TODMIN(a0) ;Ja, Minuten auf Null setzen
- move #0,ccr ;und Stunden erhöhen
- move.b #1,d0
- move.b TODHR(a0),d1
- and.b #$1f,d1 ;AM/PM ausmaskieren
- abcd d0,d1
- and.b #$80,TODHR(a0) ;Stunden schreiben, AM/PM lassen
- or.b d1,TODHR(a0)
-
- cmp.b #$12,d1 ;Über 12?
- blo CiaATODDone
-
- and.b #$1f,TODHR(a0) ;Ja, Stunden auf Null setzen
- eor.b #$80,TODHR(a0) ;und AM/PM umdrehen
-
- CiaATODDone move.l TOD10THS(a0),d0 ;Alarmzeit erreicht?
- cmp.l ALM10THS(a0),d0
- bne CiaATODNop
- move.b ICR(a0),d0 ;Ja, IRQ-Bit setzen
- or.b #$04,d0
- btst #2,INTMASK(a0) ;IRQ freigegeben?
- beq CiaATODNoIRQ
- or.b #$80,d0 ;Ja, IR-Bit setzen
- st.b IntIsCIAIRQ ;und IRQ auslösen
- CiaATODNoIRQ move.b d0,ICR(a0)
- CiaATODNop
-
- *
- * CIA-B
- *
-
- lea Registers2,a0
- subq.b #1,TODDIV(a0) ;Frequenzteiler herabzählen
- bpl CiaBTODNop
-
- btst #7,CRA(a0) ;Untergelaufen,
- beq CiaBTOD60Hz ; je nach 50/60Hz-Flag neu laden
- move.b #4,TODDIV(a0)
- bra CiaBTODLoaded
- CiaBTOD60Hz move.b #5,TODDIV(a0)
-
- CiaBTODLoaded move #0,ccr ;X löschen
- move.b #1,d0 ;1/10 Sekunden erhöhen
- move.b TOD10THS(a0),d1
- abcd d0,d1
- move.b d1,TOD10THS(a0)
- cmp.b #$10,d1 ;Über 10?
- blo CiaBTODDone
-
- clr.b TOD10THS(a0) ;Ja, 1/10 Sekunden auf Null setzen
- move #0,ccr ;und Sekunden erhöhen
- move.b #1,d0
- move.b TODSEC(a0),d1
- abcd d0,d1
- move.b d1,TODSEC(a0)
- cmp.b #$60,d1 ;Über 60?
- blo CiaBTODDone
-
- clr.b TODSEC(a0) ;Ja, Sekunden auf Null setzen
- move #0,ccr ;und Minuten erhöhen
- move.b #1,d0
- move.b TODMIN(a0),d1
- abcd d0,d1
- move.b d1,TODMIN(a0)
- cmp.b #$60,d1 ;Über 60?
- blo CiaBTODDone
-
- clr.b TODMIN(a0) ;Ja, Minuten auf Null setzen
- move #0,ccr ;und Stunden erhöhen
- move.b #1,d0
- move.b TODHR(a0),d1
- and.b #$1f,d1 ;AM/PM ausmaskieren
- abcd d0,d1
- and.b #$80,TODHR(a0) ;Stunden schreiben, AM/PM lassen
- or.b d1,TODHR(a0)
-
- cmp.b #$12,d1 ;Über 12?
- blo CiaBTODDone
-
- and.b #$1f,TODHR(a0) ;Ja, Stunden auf Null setzen
- eor.b #$80,TODHR(a0) ;und AM/PM umdrehen
-
- CiaBTODDone move.l TOD10THS(a0),d0 ;Alarmzeit erreicht?
- cmp.l ALM10THS(a0),d0
- bne CiaBTODNop
- move.b ICR(a0),d0 ;Ja, IRQ-Bit setzen
- or.b #$04,d0
- btst #2,INTMASK(a0) ;IRQ freigegeben?
- beq CiaBTODNoIRQ
- or.b #$80,d0 ;Ja, IR-Bit setzen
- tst.b NMIState ;NMI schon ausgelöst?
- bne 1$
- st.b NMIState ;Nein, NMI auslösen
- st.b IntIsNMI
- 1$
- CiaBTODNoIRQ move.b d0,ICR(a0)
- CiaBTODNop
-
- *
- * Joystickabfrage
- *
-
- lea Registers1,a0
-
- ; Port 1
- move.b #$ff,d2 ;Vorgabe: Joystick inaktiv
- tst.w Joystick1On(pc)
- beq 15$
-
- btst #6,$bfe001 ;Feuerknopf
- bne 11$
- bclr #4,d2
-
- 11$ move.w $dff00a,d0
- btst #1,d0 ;Rechts
- beq 12$
- bclr #3,d2
-
- 12$ btst #9,d0 ;Links
- beq 13$
- bclr #2,d2
-
- 13$ move.w d0,d1
- add.w d0,d0
- eor.w d1,d0
- btst #1,d0 ;Runter
- beq 14$
- bclr #1,d2
-
- 14$ btst #9,d0 ;Hoch
- beq 15$
- bclr #0,d2
-
- 15$ move.b d2,Joystick1
-
- ; Port 2
- move.b Joystick2Key,d2 ;Vorgabe: Zehnerblock-Emulation
- tst.w Joystick2On(pc)
- beq 25$
-
- btst #7,$bfe001 ;Feuerknopf
- bne 21$
- bclr #4,d2
-
- 21$ move.w $dff00c,d0
- btst #1,d0 ;Rechts
- beq 22$
- bclr #3,d2
-
- 22$ btst #9,d0 ;Links
- beq 23$
- bclr #2,d2
-
- 23$ move.w d0,d1
- add.w d0,d0
- eor.w d1,d0
- btst #1,d0 ;Runter
- beq 24$
- bclr #1,d2
-
- 24$ btst #9,d0 ;Hoch
- beq 25$
- bclr #0,d2
-
- 25$ move.b d2,Joystick2
-
- ; Joysticks vertauschen?
- tst.w JoystickSwap(pc)
- beq 30$
- move.b Joystick1,d0
- move.b Joystick2,Joystick1
- move.b d0,Joystick2
- 30$ rts
-
-
- **
- ** Taste wurde gedrückt
- **
-
- _KeyPressed move.l 4(sp),d0
- lea KeyMatrix,a0
-
- bclr #7,d0 ;KeyUp/KeyDown
- bne KeyUp
-
- cmp.b #$40,d0
- bhs KeyDownSpecial
- and.w #$003f,d0 ;$00..$3f
-
- cmp.b #$0f,d0 ;Joystick-Emulation
- beq KeyDownJoyFire
- cmp.b #$1d,d0
- beq KeyDownJoyDL
- cmp.b #$1e,d0
- beq KeyDownJoyDown
- cmp.b #$1f,d0
- beq KeyDownJoyDR
- cmp.b #$2d,d0
- beq KeyDownJoyLeft
- cmp.b #$2e,d0
- beq KeyDownJoyFire
- cmp.b #$2f,d0
- beq KeyDownJoyRight
- cmp.b #$3d,d0
- beq KeyDownJoyUL
- cmp.b #$3e,d0
- beq KeyDownJoyUp
- cmp.b #$3f,d0
- beq KeyDownJoyUR
-
- movem.w KeyTable(pc,d0.w*4),d0/d1
- bclr d1,(a0,d0.w)
- rts
-
- KeyUp cmp.b #$40,d0
- bhs KeyUpSpecial
- and.w #$003f,d0 ;$00..$3f
-
- cmp.b #$0f,d0 ;Joystick-Emulation
- beq KeyUpJoyFire
- cmp.b #$1d,d0
- beq KeyUpJoyDL
- cmp.b #$1e,d0
- beq KeyUpJoyDown
- cmp.b #$1f,d0
- beq KeyUpJoyDR
- cmp.b #$2d,d0
- beq KeyUpJoyLeft
- cmp.b #$2e,d0
- beq KeyUpJoyFire
- cmp.b #$2f,d0
- beq KeyUpJoyRight
- cmp.b #$3d,d0
- beq KeyUpJoyUL
- cmp.b #$3e,d0
- beq KeyUpJoyUp
- cmp.b #$3f,d0
- beq KeyUpJoyUR
-
- movem.w KeyTable(pc,d0.w*4),d0/d1
- bset d1,(a0,d0.w)
- KeyNOP rts
-
- KeyDownSpecial sub.b #$40,d0
- cmp.b #$20,d0
- bhs KeyDownMod
- and.w #$1f,d0 ;$40..$5f
- jmp ([KeyDownSpecTab,pc,d0.w*4])
-
- KeyDownMod sub.b #$20,d0
- cmp.b #$08,d0
- bhs KeyNOP
- and.w #$07,d0 ;$60..$67
- cmp.w #$07,d0 ;Amiga rechts ignorieren
- beq 1$
- movem.w KeyModTable(pc,d0.w*4),d0/d1
- bclr d1,(a0,d0.w)
- 1$ rts
-
- KeyUpSpecial sub.b #$40,d0
- cmp.b #$20,d0
- bhs KeyUpMod
- and.w #$1f,d0 ;$40..$5f
- jmp ([KeyUpSpecTab,pc,d0.w*4])
-
- KeyUpMod sub.b #$20,d0
- cmp.b #$08,d0
- bhs KeyNOP
- and.w #$07,d0 ;$60..$67
- cmp.w #$07,d0 ;Amiga rechts ignorieren
- beq 1$
- movem.w KeyModTable(pc,d0.w*4),d0/d1
- bset d1,(a0,d0.w)
- 1$ rts
-
- KeySpaceD bclr #4,7(a0)
- rts
- KeySpaceU bset #4,7(a0)
- rts
- KeyBackD bclr #0,(a0)
- rts
- KeyBackU bset #0,(a0)
- rts
- KeyEnterD
- KeyReturnD bclr #1,(a0)
- rts
- KeyEnterU
- KeyReturnU bset #1,(a0)
- rts
- KeyEscD bclr #7,7(a0)
- rts
- KeyEscU bset #7,7(a0)
- rts
- KeyDeleteD bclr #3,6(a0)
- rts
- KeyDeleteU bset #3,6(a0)
- rts
- KeyUpD bclr #4,6(a0)
- bclr #7,(a0)
- rts
- KeyUpU bset #4,6(a0)
- bset #7,(a0)
- rts
- KeyDownD bclr #7,(a0)
- rts
- KeyDownU bset #7,(a0)
- rts
- KeyRightD bclr #2,(a0)
- rts
- KeyRightU bset #2,(a0)
- rts
- KeyLeftD bclr #4,6(a0)
- bclr #2,(a0)
- rts
- KeyLeftU bset #4,6(a0)
- bset #2,(a0)
- rts
- KeyF1D bclr #4,(a0)
- rts
- KeyF1U bset #4,(a0)
- rts
- KeyF3D bclr #5,(a0)
- rts
- KeyF3U bset #5,(a0)
- rts
- KeyF5D bclr #6,(a0)
- rts
- KeyF5U bset #6,(a0)
- rts
- KeyF7D bclr #3,(a0)
- rts
- KeyF7U bset #3,(a0)
- rts
- KeyF2D bclr #4,6(a0)
- bclr #4,(a0)
- rts
- KeyF2U bset #4,6(a0)
- bset #4,(a0)
- rts
- KeyF4D bclr #4,6(a0)
- bclr #5,(a0)
- rts
- KeyF4U bset #4,6(a0)
- bset #5,(a0)
- rts
- KeyF6D bclr #4,6(a0)
- bclr #6,(a0)
- rts
- KeyF6U bset #4,6(a0)
- bset #6,(a0)
- rts
- KeyF8D bclr #4,6(a0)
- bclr #3,(a0)
- rts
- KeyF8U bset #4,6(a0)
- bset #3,(a0)
- rts
- KeyF10D jmp ResetC64
- KeyNKPlusD bclr #0,5(a0) ;+
- rts
- KeyNKPlusU bset #0,5(a0)
- rts
- KeyNKMinusD bclr #3,5(a0) ;-
- rts
- KeyNKMinusU bset #3,5(a0)
- rts
- KeyNKAsterD tst.w KeyboardYZ
- bne 1$
- bclr #1,6(a0) ;*
- rts
- 1$ bclr #5,6(a0) ;=
- rts
- KeyNKAsterU tst.w KeyboardYZ
- bne 1$
- bset #1,6(a0)
- rts
- 1$ bset #5,6(a0)
- rts
- KeyNKSlashD tst.w KeyboardYZ
- bne 1$
- bclr #7,6(a0) ;/
- rts
- 1$ bclr #6,6(a0) ;^
- rts
- KeyNKSlashU tst.w KeyboardYZ
- bne 1$
- bset #7,6(a0)
- rts
- 1$ bset #6,6(a0)
- rts
- KeyNKLeftParD bclr #4,6(a0) ;[
- bclr #5,5(a0)
- rts
- KeyNKLeftParU bset #4,6(a0)
- bset #5,5(a0)
- rts
- KeyNKRightParD bclr #4,6(a0) ;]
- bclr #2,6(a0)
- rts
- KeyNKRightParU bset #4,6(a0)
- bset #2,6(a0)
- rts
- KeyHelpD tst.b NMIState ;NMI schon ausgelöst?
- bne 1$
- st.b IntIsNMI ;Nein, NMI auslösen
- 1$ rts
-
- ; Joystick-Emulation
- KeyDownJoyUp bclr #0,Joystick2Key
- rts
- KeyDownJoyDown bclr #1,Joystick2Key
- rts
- KeyDownJoyLeft bclr #2,Joystick2Key
- rts
- KeyDownJoyRight bclr #3,Joystick2Key
- rts
- KeyDownJoyUL bclr #0,Joystick2Key
- bclr #2,Joystick2Key
- rts
- KeyDownJoyUR bclr #0,Joystick2Key
- bclr #3,Joystick2Key
- rts
- KeyDownJoyDL bclr #1,Joystick2Key
- bclr #2,Joystick2Key
- rts
- KeyDownJoyDR bclr #1,Joystick2Key
- bclr #3,Joystick2Key
- rts
- KeyDownJoyFire bclr #4,Joystick2Key
- rts
-
- KeyUpJoyUp bset #0,Joystick2Key
- rts
- KeyUpJoyDown bset #1,Joystick2Key
- rts
- KeyUpJoyLeft bset #2,Joystick2Key
- rts
- KeyUpJoyRight bset #3,Joystick2Key
- rts
- KeyUpJoyUL bset #0,Joystick2Key
- bset #2,Joystick2Key
- rts
- KeyUpJoyUR bset #0,Joystick2Key
- bset #3,Joystick2Key
- rts
- KeyUpJoyDL bset #1,Joystick2Key
- bset #2,Joystick2Key
- rts
- KeyUpJoyDR bset #1,Joystick2Key
- bset #3,Joystick2Key
- rts
- KeyUpJoyFire bset #4,Joystick2Key
- rts
-
-
- **
- ** Datenbereich
- **
-
- CNOP 0,4
- Registers1 ds.b 32 ;CIA-A-Register
- Registers2 ds.b 32 ;CIA-B-Register
-
- CIACycles dc.w 0 ;Anzahl Phi2-Zyklen pro Rasterzeile (für Timer)
- Joystick1On dc.w 0 ;Joystick an Port 1 wird abgefragt
- Joystick2On dc.w 0 ;Joystick an Port 2 wird abgefragt
- JoystickSwap dc.w 0 ;Joysticks vertauschen
- KeyboardYZ dc.w 0 ;Amerikanische Tastaturbelegung
-
- Joystick1 dc.b 0 ;Joystick 1 AND-Wert
- Joystick2 dc.b 0 ;Joystick 2 AND-Wert
- Joystick2Key dc.b 0 ;Joystick 2 AND-Wert für Emulation über Zehnerblock
-
- ; Tastaturübersetzungstabelle:
- ; Für jeden Amiga-RawKey Spalte und Zeile in der KeyMatrix
- CNOP 0,4
- KeyTable dc.w 7,1 ;` -> <-
- dc.w 7,0 ;1
- dc.w 7,3 ;2
- dc.w 1,0 ;3
- dc.w 1,3 ;4
- dc.w 2,0 ;5
- dc.w 2,3 ;6
- dc.w 3,0 ;7
- dc.w 3,3 ;8
- dc.w 4,0 ;9
- dc.w 4,3 ;0
- dc.w 5,0 ;ß -> +
- dc.w 5,3 ;´ -> -
- dc.w 6,0 ;\ -> £
- dc.w 0,0
- dc.w 4,3 ;NP 0
-
- dc.w 7,6 ;Q
- dc.w 1,1 ;W
- dc.w 1,6 ;E
- dc.w 2,1 ;R
- dc.w 2,6 ;T
- KeyPatch1 dc.w 1,4 ;Y -> Z
- dc.w 3,6 ;U
- dc.w 4,1 ;I
- dc.w 4,6 ;O
- dc.w 5,1 ;P
- dc.w 5,6 ;ü -> @
- dc.w 6,1 ;+ -> *
- dc.w 0,0
- dc.w 7,0 ;NP 1
- dc.w 7,3 ;NP 2
- dc.w 1,0 ;NP 3
-
- dc.w 1,2 ;A
- dc.w 1,5 ;S
- dc.w 2,2 ;D
- dc.w 2,5 ;F
- dc.w 3,2 ;G
- dc.w 3,5 ;H
- dc.w 4,2 ;J
- dc.w 4,5 ;K
- dc.w 5,2 ;L
- dc.w 5,5 ;ö -> :
- dc.w 6,2 ;ä -> ;
- dc.w 6,5 ;# -> =
- dc.w 0,0
- dc.w 1,3 ;NP 4
- dc.w 2,0 ;NP 5
- dc.w 2,3 ;NP 6
-
- dc.w 6,6 ;< -> ^
- KeyPatch2 dc.w 3,1 ;Z -> Y
- dc.w 2,7 ;X
- dc.w 2,4 ;C
- dc.w 3,7 ;V
- dc.w 3,4 ;B
- dc.w 4,7 ;N
- dc.w 4,4 ;M
- dc.w 5,7 ;,
- dc.w 5,4 ;.
- dc.w 6,7 ;- -> /
- dc.w 0,0
- dc.w 5,4 ;NP .
- dc.w 3,0 ;NP 7
- dc.w 3,3 ;NP 8
- dc.w 4,0 ;NP 9
-
- KeyDownSpecTab dc.l KeySpaceD
- dc.l KeyBackD
- dc.l KeyNOP
- dc.l KeyEnterD
- dc.l KeyReturnD
- dc.l KeyEscD
- dc.l KeyDeleteD
- dc.l KeyNOP
-
- dc.l KeyNOP
- dc.l KeyNOP
- dc.l KeyNKMinusD
- dc.l KeyNOP
- dc.l KeyUpD
- dc.l KeyDownD
- dc.l KeyRightD
- dc.l KeyLeftD
-
- dc.l KeyF1D
- dc.l KeyF2D
- dc.l KeyF3D
- dc.l KeyF4D
- dc.l KeyF5D
- dc.l KeyF6D
- dc.l KeyF7D
- dc.l KeyF8D
-
- dc.l KeyNOP
- dc.l KeyF10D
- dc.l KeyNKLeftParD
- dc.l KeyNKRightParD
- dc.l KeyNKSlashD
- dc.l KeyNKAsterD
- dc.l KeyNKPlusD
- dc.l KeyHelpD
-
- KeyUpSpecTab dc.l KeySpaceU
- dc.l KeyBackU
- dc.l KeyNOP
- dc.l KeyEnterU
- dc.l KeyReturnU
- dc.l KeyEscU
- dc.l KeyDeleteU
- dc.l KeyNOP
-
- dc.l KeyNOP
- dc.l KeyNOP
- dc.l KeyNKMinusU
- dc.l KeyNOP
- dc.l KeyUpU
- dc.l KeyDownU
- dc.l KeyRightU
- dc.l KeyLeftU
-
- dc.l KeyF1U
- dc.l KeyF2U
- dc.l KeyF3U
- dc.l KeyF4U
- dc.l KeyF5U
- dc.l KeyF6U
- dc.l KeyF7U
- dc.l KeyF8U
-
- dc.l KeyNOP
- dc.l KeyNOP
- dc.l KeyNKLeftParU
- dc.l KeyNKRightParU
- dc.l KeyNKSlashU
- dc.l KeyNKAsterU
- dc.l KeyNKPlusU
- dc.l KeyNOP
-
- KeyModTable dc.w 1,7 ;Shift left
- dc.w 6,4 ;Shift right
- dc.w 1,7 ;Caps lock -> Shift left
- dc.w 7,2 ;Control
- dc.w 7,5 ;Alt left -> C=
- dc.w 7,5 ;Alt right -> C=
- dc.w 7,5 ;Amiga left -> C=
- dc.w 0,0 ;Amiga right
-
- ; Bit 7 6 5 4 3 2 1 0
- ; 0 CUD F5 F3 F1 F7 CLR RET DEL
- ; 1 SHL E S Z 4 A W 3
- ; 2 X T F C 6 D R 5
- ; 3 V U H B 8 G Y 7
- ; 4 N O K M 0 J I 9
- ; 5 , @ : . - L P +
- ; 6 / ^ = SHR HOM ; * £
- ; 7 R/S Q C= SPC 2 CTL <- 1
-
- KeyMatrix ds.b 8 ;C64-Tastaturmatrix pro Taste ein Bit
- ;0: Taste gedrückt
-
- END
-